package com.hgl.bi.web.aop;

import com.hgl.bi.common.annotation.RequirePmt;
import com.hgl.bi.common.constant.ErrorCode;
import com.hgl.bi.common.exception.BusinessException;
import com.hgl.bi.common.manager.RedisManager;
import com.hgl.bi.web.model.dto.UserInfoDto;
import com.hgl.bi.web.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @program: BI
 * @description: 权限校验切面
 * @author: hgl
 * @create: 2025-03-30 16:51
 */
@Aspect
@Component
public class AuthAspect {

    @Autowired
    private RedisManager redisManager;

    @Autowired
    private UserService userService;

    @Around("@annotation(requirePmt)") // 定义切点
    public Object checkAuth(ProceedingJoinPoint joinPoint, RequirePmt requirePmt) throws Throwable {

        String code = requirePmt.code();

        // 不需要权限，放行
        if (code == null) {
            return joinPoint.proceed();
        }

        // 获取当前请求的 HttpServletRequest 对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();

            // 从请求头中获取 token 值
            String satoken = request.getHeader("satoken");

            // 验证权限
            if (satoken != null) {

                // 获取权限名称
                UserInfoDto userInfo = (UserInfoDto) redisManager
                        .get("satoken:" + satoken, UserInfoDto.class);
                Long userId = userInfo.getId();
                List<String> userPermissions = userService.getUserPermissions(userId);

                // 将 List 转换为 Set
                Set<String> permissionSet = new HashSet<>(userPermissions);

                if (!permissionSet.contains(code)) {
                    throw new BusinessException(ErrorCode.PERMISSION_NOT_EXISTS);
                }

            } else {
                throw new BusinessException(ErrorCode.NOT_LOGIN);
            }
        } else {
            throw new BusinessException(ErrorCode.CONTEXT_IS_NULL);
        }
        return joinPoint.proceed();
    }

}
